from datetime import datetime
from src.weather_api import WeatherAPI
from src.data_handler import DataHandler
from src.crawler import SportFieldCrawler

class RunningReminder:
    """
    跑步提醒生成器，结合天气和操场开放时间生成跑步建议
    """
    
    def __init__(self):
        self.weather_api = WeatherAPI()
        self.data_handler = DataHandler()
        self.crawler = SportFieldCrawler()
    
    def update_data_if_needed(self):
        """检查并更新开放时间数据（如果需要）"""
        # 尝试加载现有数据
        open_hours_data = self.data_handler.load_open_hours()
        
        # 如果没有数据或数据过旧（超过24小时），重新爬取
        if not open_hours_data:
            print("没有找到开放时间数据，开始爬取...")
            self.crawler.run()
        else:
            # 检查数据是否过旧
            try:
                crawl_time_str = open_hours_data.get('crawl_time', '')
                if crawl_time_str:
                    crawl_time = datetime.strptime(crawl_time_str, '%Y-%m-%d %H:%M:%S')
                    # 计算与当前时间的差距（小时）
                    hours_diff = (datetime.now() - crawl_time).total_seconds() / 3600
                    
                    if hours_diff > 24:
                        print("开放时间数据已超过24小时，更新数据...")
                        self.crawler.run()
            except ValueError:
                print("时间格式错误，重新爬取数据...")
                self.crawler.run()
    
    def generate_today_reminder(self):
        """生成今日跑步提醒"""
        # 更新数据
        self.update_data_if_needed()
        
        # 获取今日开放时间
        today_hours = self.data_handler.get_today_open_hours()
        
        # 获取当前天气
        current_weather = self.weather_api.get_current_weather()
        
        # 评估跑步适宜性
        suitability = self.weather_api.evaluate_running_suitability(current_weather)
        
        # 组装提醒信息
        reminder = {
            'date': datetime.now().strftime('%Y-%m-%d'),
            'time': datetime.now().strftime('%H:%M:%S'),
            'weather': current_weather,
            'suitability': suitability,
            'open_hours': today_hours,
            'recommendations': []
        }
        
        # 生成推荐
        self._generate_recommendations(reminder)
        
        return reminder
    
    def _generate_recommendations(self, reminder):
        """根据天气和开放时间生成具体建议"""
        recommendations = []
        
        # 检查操场开放情况
        if not reminder['open_hours']:
            recommendations.append("今日未找到操场开放信息，请自行确认。")
        else:
            # 提取开放时间段信息
            time_slots = reminder['open_hours'].get('time_slots', [])
            if not time_slots:
                recommendations.append("今日操场可能不开放，请自行确认。")
            else:
                open_times_text = "、".join([f"{slot['start']}-{slot['end']}" 
                                          for slot in time_slots])
                recommendations.append(f"今日操场开放时间：{open_times_text}")
                
                # 检查是否开放备注
                note = reminder['open_hours'].get('note', '')
                if note:
                    recommendations.append(f"开放备注：{note}")
        
        # 根据天气适宜性生成建议
        if reminder['suitability']['score'] >= 80:
            recommendations.append("💯 今日天气极佳，非常适合跑步！")
            recommendations.append(self._get_optimal_time_suggestion(reminder))
        elif reminder['suitability']['score'] >= 60:
            recommendations.append("👍 今日天气不错，适合进行跑步活动。")
        elif reminder['suitability']['score'] >= 40:
            recommendations.append("😐 今日天气一般，建议适当调整运动强度。")
            recommendations.append(self._get_weather_precautions(reminder))
        else:
            recommendations.append("👎 今日天气条件不太适合户外跑步。")
            recommendations.append("建议考虑室内运动替代方案，如健身房、室内跑道等。")
        
        # 添加着装建议
        recommendations.append(self._get_clothing_suggestion(reminder))
        
        # 添加补充水分建议
        recommendations.append(self._get_hydration_suggestion(reminder))
        
        reminder['recommendations'] = recommendations
    
    def _get_optimal_time_suggestion(self, reminder):
        """获取今日最佳跑步时间建议"""
        # 这里简单实现，实际可以根据天气预报和开放时间给出更精确的建议
        current_hour = datetime.now().hour
        
        # 根据当前时间给出建议
        if current_hour < 10:
            return "早晨空气清新，是跑步的好时机！"
        elif current_hour < 16:
            return "午后阳光充足，但注意防晒。"
        else:
            return "傍晚温度适宜，是一天中很适合跑步的时段。"
    
    def _get_weather_precautions(self, reminder):
        """获取天气注意事项"""
        weather = reminder['weather']
        precautions = []
        
        # 根据天气状况添加注意事项
        if weather['temperature'] < 10:
            precautions.append("注意保暖，避免运动过度导致感冒。")
        elif weather['temperature'] > 30:
            precautions.append("温度较高，建议减少运动量，避免中暑。")
        
        if weather['humidity'] > 80:
            precautions.append("湿度较大，注意补充水分。")
        
        if weather['wind_speed'] > 8:
            precautions.append("风力较大，跑步时注意安全。")
        
        if weather['is_raining']:
            precautions.append("有降雨，建议携带雨具或改期。")
        
        return precautions[0] if precautions else ""
    
    def _get_clothing_suggestion(self, reminder):
        """获取着装建议"""
        temp = reminder['weather']['temperature']
        
        if temp < 5:
            return "👕 今日较冷，建议穿着保暖的运动衣物，戴帽子和手套。"
        elif temp < 15:
            return "👕 今日凉爽，建议穿着长袖运动衫和长裤。"
        elif temp < 25:
            return "👕 今日温度适中，短袖短裤即可。"
        else:
            return "👕 今日较热，穿着轻薄透气的运动衣物，注意防晒。"
    
    def _get_hydration_suggestion(self, reminder):
        """获取水分补充建议"""
        weather = reminder['weather']
        
        # 根据温度和湿度给出建议
        if weather['temperature'] > 25 or weather['humidity'] > 70:
            return "💧 今日需要特别注意补充水分，建议运动前、中、后都要喝水。"
        else:
            return "💧 记得携带水壶，保持适当的水分摄入。"
    
    def format_reminder_text(self, reminder):
        """格式化提醒信息为文本"""
        output = []
        output.append(f"📅 校园跑步提醒 - {reminder['date']}")
        output.append("=" * 40)
        
        # 天气信息
        output.append("\n🌤️ 当前天气情况：")
        output.append(f"   温度：{reminder['weather']['temperature']}°C")
        output.append(f"   天气状况：{reminder['weather']['weather']}")
        output.append(f"   湿度：{reminder['weather']['humidity']}%")
        output.append(f"   风速：{reminder['weather']['wind_speed']}m/s")
        
        # 跑步适宜性
        output.append("\n🏃 跑步适宜性评估：")
        output.append(f"   得分：{reminder['suitability']['score']}/100")
        output.append(f"   总体建议：{reminder['suitability']['advice']}")
        
        # 详细评估
        output.append("\n📊 详细评估：")
        for key, item in reminder['suitability']['details'].items():
            output.append(f"   {item['message']}")
        
        # 开放时间
        output.append("\n⏰ 操场开放信息：")
        if reminder['open_hours']:
            time_slots = reminder['open_hours'].get('time_slots', [])
            if time_slots:
                open_times = "、".join([f"{slot['start']}-{slot['end']}" 
                                      for slot in time_slots])
                output.append(f"   开放时间：{open_times}")
            
            note = reminder['open_hours'].get('note', '')
            if note:
                output.append(f"   备注：{note}")
        else:
            output.append("   未获取到开放时间信息")
        
        # 推荐建议
        output.append("\n💡 今日跑步建议：")
        for rec in reminder['recommendations']:
            output.append(f"   {rec}")
        
        output.append("\n💪 生命在于运动，祝您跑步愉快！")
        
        return "\n".join(output)
    
    def get_best_running_time_today(self):
        """获取今日最佳跑步时间段"""
        # 获取天气预报
        forecast = self.weather_api.get_weather_forecast(days=1)
        
        # 获取开放时间
        today_hours = self.data_handler.get_today_open_hours()
        
        if not today_hours or 'time_slots' not in today_hours:
            return "无法确定最佳跑步时间，未找到操场开放信息。"
        
        # 简单算法：根据开放时间和天气状况推荐最佳时段
        open_slots = today_hours['time_slots']
        
        # 这里简化处理，实际可以根据一天的天气预报给出更详细的建议
        best_slot = open_slots[0]  # 默认选择第一个时段
        
        # 尝试找到温度最适宜的时段
        # 实际应用中可以结合更详细的天气预报数据
        current_temp = self.weather_api.get_current_weather()['temperature']
        
        if len(open_slots) > 1:
            # 如果有早晚两个时段，根据当前季节和温度做推荐
            morning_slot = open_slots[0]
            afternoon_slot = open_slots[1]
            
            # 简单规则：温度低于20度推荐下午，高于25度推荐早上
            if current_temp < 20:
                best_slot = afternoon_slot
            elif current_temp > 25:
                best_slot = morning_slot
        
        return f"今日最佳跑步时间：{best_slot['start']} - {best_slot['end']}"


if __name__ == "__main__":
    # 示例使用
    reminder = RunningReminder()
    
    # 生成今日提醒
    today_reminder = reminder.generate_today_reminder()
    
    # 格式化输出
    formatted_text = reminder.format_reminder_text(today_reminder)
    print(formatted_text)
    
    # 获取最佳跑步时间
    print("\n" + reminder.get_best_running_time_today())